package com.qigao.mall.commons.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

public class PayUtil {

    private static final Logger logger= LoggerFactory.getLogger(PayUtil.class);
    /**

     * 随机获取字符串

     * 包含数字和小写字母

     * @param length 随机字符串长度

     * @return 随机字符串

     */
    public static String getRandomString(int length) {
        if ( length <= 0 || length > 32) {
            throw new IllegalArgumentException("参数必须大于0并且不大于32");
        }
        char[] randomChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a','b','c','d','e','f','g','h','i','j',
                'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u','v','w','x','y','z'};
        Random rand = new Random();
        StringBuilder sb = new StringBuilder();
        int N = randomChar.length;
        for (int i = 0; i < length; i++) {
            sb.append(randomChar[rand.nextInt(N)]);
        }
        return sb.toString();
    }

    /**

     * 生成时间戳

     * @return

     */
    public  static String createTimestamp() {
        return (System.currentTimeMillis() / 1000) + "";
    }

    /**

     * 签名算法

     * @param params

     * @return

     */
    public static String createSign(Map<String, String> params,String signType,String apiKey) {
       String contentStr=PairString.createLinkString(params);
        //拼接秘钥
        contentStr=contentStr+"&key=" + apiKey;
        logger.info("signType=[{}]contentStr=[{}]",signType,contentStr);
        String signStr = MD5Util.getMD5(contentStr).toUpperCase();
        if("HMAC-SHA256".equals(signType)){
            signStr=createSha256Sign(contentStr,apiKey);
        }
        return signStr;
    }

    public static String createSha256Sign(String contentStr, String apiKey) {
        try{
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(apiKey.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] array = sha256_HMAC.doFinal(contentStr.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString().toUpperCase();
        }catch (Exception e){
            logger.error("生成sign发生异常:{}",e);
            return null;
        }
    }

    public static String decryptData(String signData,String key){
        try{
            return AESUtil.decryptData(key,signData);
        }catch (Exception e){
            logger.error("解密异常:{}{}",signData,e);
            return null;
        }

    }

    /**

     * 根据时间策略生成商品订单号

     * @return

     */
    public static String getOutTradeNo() {
        StringBuilder sb = new StringBuilder();
        sb.append(System.currentTimeMillis());
        Random rand = new Random();
        for(int i = 0; i < 3; i++) {
            sb.append(rand.nextInt(10));
        }
        return sb.toString();
    }

    /**

     * 将map参数集合转化为xml格式

     * @return

     */
    public static String mapToXml(Map<String, String> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        for(Map.Entry<String, String> entry : map.entrySet()) {
            if(Objects.equals("sign", entry.getKey()))
                continue;
            sb.append("<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">");
        }
        if(map.containsKey("sign"))
            sb.append("<" + "sign" + ">" + map.get("sign") + "</" + "sign" + ">");
        sb.append("</xml>");
        return sb.toString();
    }


    /**

     * sha1加密算法

     * @param str

     * @return

     */
    public static String getSha1(String str){
        if(str==null||str.length()==0){
            return null;
        }
        char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
                'a','b','c','d','e','f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j*2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }



    /**
     * 将加密后的字节数组转换成字符串
     *
     * @param b 字节数组
     * @return 字符串
     */
    public  static String byteArrayToHexString(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b!=null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }
    /**
     * sha256_HMAC加密
     * @param message 消息
     * @param key  秘钥
     * @return 加密后字符串
     */
    public static String sha256_HMAC(Map<String,String> message, String key) {
        Mac sha256_HMAC;
        String contentStr = PairString.createLinkString(message);
        //拼接秘钥
        contentStr = contentStr + "&key=" + key;
        try {
            sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            StringBuilder sb = new StringBuilder();
            byte[] array = sha256_HMAC.doFinal(contentStr.getBytes("UTF-8"));
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString().toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
